﻿using Ldt.DataEngine.RuleAssemble;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.DataModel;
using LdtJudge.DataEngine.Model.DataModel.DataParseStorage;
using LdtJudge.DataEngine.Model.Personnel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace LdtDataEngin.ModuleDetail.BaseModule.PersonnelBase
{
    public class ElementExtractBase
    {
        #region 基础数据
        /// <summary>
        /// 交互数据层
        /// </summary>
        public DataContext dataContext { get; set; }

        private List<An_anjianshiti> caseEntityInfoList;

        //人员判断
        private static Regex SpokeParagraphSplit = new Regex(@"(^|\s[审长问仲？?][^\r]*[:：][^\r]+).*?(?=\s[审长问仲？?][^\r]*[:：]|$)", RegexOptions.Singleline);//发言段落拆分

        private static string SentenseFormat = @"(({0})[:：]|^).+?(?=(?:{0})[:：]|$)";//发言分句

        private static Regex SpokeNameParse = new Regex(@"(?<=\r\s*|^)\S{1,20}(?=[：:])");

        private int JudgerCount = 1;

        /// <summary>
        /// 人员信息表结合
        /// </summary>
        private List<ElementSpokeName> spokenamelist = new List<ElementSpokeName>();

        /// <summary>
        /// 人员段落发言集合
        /// </summary>
        public List<ElementExtractText> spokeText = new List<ElementExtractText>();
        /// <summary>
        /// 发言人代称
        /// </summary>
        private List<string> allSpokeShortName = new List<string>();

        /// <summary>
        /// 人员转换
        /// </summary>
        private PersonnelAnalysisBase personnelAnalysis = new PersonnelAnalysisBase();
        #endregion


        /// <summary>
        /// 人员段落分析
        /// </summary>
        /// <param name="analysisFactListItemsList">发言人对话提取分析配置(从配置平台获取)</param>
        public void ParesElement(List<ParagraphAnalysisFactListItem> analysisFactListItemsList)
        {
            // 得到人员实体，之后对照人员实体与对话段落得到各个人员说过的话
            caseEntityInfoList = dataContext.DataLayerAns.Anjianshitis; 
            // 遍历文书段落，提取人员对话
            foreach (An_duanluo paragrapItem in dataContext.DataLayerAns.Duanluos)
            {
                ParagraphAnalysisFactListItem paragraphAnalysisFactListItem = analysisFactListItemsList.FirstOrDefault(a => a.AnanlysisCode.ToLower() == paragrapItem.Duanluobianhao.ToLower());
                if (paragraphAnalysisFactListItem != null)
                {
                    if (paragraphAnalysisFactListItem.IsAnalysisTalk == "0")
                    {
                        ///表示不需要进行分析人员对话内容的拆分
                        ParseSingleParagraphNoSplit(paragrapItem, paragraphAnalysisFactListItem);
                    }
                    else if (paragraphAnalysisFactListItem.IsAnalysisTalk == "1")
                    {

                        ///表示需要进行分析人员对话内容的拆分
                        ParseSingleParagraphWithSplit(paragrapItem, paragraphAnalysisFactListItem);
                    }
                }
            }
            dataContext.DataLayerAns.SpokeTextDialogue = spokeText;
        }

        #region 人员对象获取/对话拆分
        /// <summary>
        /// 不需要进行分析人员对话内容的拆分
        /// </summary>
        /// <param name="sD_ParagraphTXTModel"></param>
        public void ParseSingleParagraphNoSplit(An_duanluo sD_ParagraphTXTModel, ParagraphAnalysisFactListItem paragraphAnalysisFactListItem)
        {
            //获取当前角色的人员信息
            var speekPersonIdList = paragraphAnalysisFactListItem.SpeekPersonID?.Split(",").ToList()?? new List<string>();
            var agentList = paragraphAnalysisFactListItem.Agent?.Split(",").ToList()?? new List<string>();
            List<string> inquirerList = paragraphAnalysisFactListItem.Inquirer?.Split(",").ToList() ?? new List<string>();
            List<ElementSpokeName> relatMen = spokenamelist.Where(a => a.ES_SuitDrgreeID == paragraphAnalysisFactListItem.SpeekPersonID).ToList();

            foreach (ElementSpokeName man in spokenamelist)
            {
                if (speekPersonIdList.Contains(man.ES_SuitDrgreeID) || agentList.Contains(man.ES_SuitDrgreeID))
                {
                    ElementExtractText model = new ElementExtractText();
                    model.E_ID = Snowflake.Instance().GetId().ToString();
                    model.OriginalText = "\r\n" + sD_ParagraphTXTModel.Duanluoneirong;
                    model.ParagraphCode = sD_ParagraphTXTModel.Duanluobianhao;
                    model.SpokesmanID = "";
                    model.FL_ID = "0";
                    model.SpokesmanName = man.ES_ShortName;
                    model.AssertorID = man.ES_ProxyName;
                    model.AssertorName = man.ES_FullName;
                    model.AssertorAlias = man.ES_ShortName;
                    model.AssertorSuitdegreeID = man.ES_SuitDrgreeID;
                    model.ParagraphName = paragraphAnalysisFactListItem.Code_Ch_Name;
                    model.SourceID = "0";
                    spokeText.Add(model);
                }
                else if(inquirerList.Contains(man.ES_SuitDrgreeID))
                {
                    List<ElementSpokeName> relatt = spokenamelist.Where(a => inquirerList.Contains(a.ES_SuitDrgreeID)).ToList();
                    ElementExtractText model = new ElementExtractText();
                    model.E_ID = Snowflake.Instance().GetId().ToString();
                    model.OriginalText = "\r\n" + sD_ParagraphTXTModel.Duanluoneirong;
                    model.ParagraphCode = sD_ParagraphTXTModel.Duanluobianhao;
                    model.SpokesmanID = "";
                    model.FL_ID = "";
                    model.SpokesmanName = man.ES_ShortName;
                    if (relatt.Count > 0)
                    {
                        model.AssertorID = relatt[0].ES_SuitDrgreeID;
                        model.AssertorName = relatt[0].ES_FullName;
                        model.AssertorAlias = relatt[0].ES_ShortName;
                        model.AssertorSuitdegreeID = relatt[0].ES_SuitDrgreeID;
                    }

                    model.ParagraphName = paragraphAnalysisFactListItem.Code_Ch_Name;
                    model.SourceID = "";
                    spokeText.Add(model);
                }
                else
                {
                    //ElementExtractText model = new ElementExtractText();
                    //model.E_ID = Snowflake.Instance().GetId().ToString();
                    //model.OriginalText = "\r\n" + sD_ParagraphTXTModel.Duanluoneirong;
                    //model.ParagraphCode = sD_ParagraphTXTModel.Duanluobianhao;
                    //model.ParagraphName = paragraphAnalysisFactListItem.Code_Ch_Name;
                    //model.FL_ID = "0";
                    //model.SourceID = "0";
                    //spokeText.Add(model);
                }

            }
        }

        /// <summary>
        /// 需要进行人员对话拆分的段落
        /// </summary>
        /// <param name="sD_ParagraphTXTModel">段落实体</param>
        /// <param name="paragraphAnalysisFactListItem">段落配置</param>
        public void ParseSingleParagraphWithSplit(An_duanluo sD_ParagraphTXTModel, ParagraphAnalysisFactListItem paragraphAnalysisFactListItem)
        {
            string originalText = "\r\n" + sD_ParagraphTXTModel.Duanluoneirong.Trim();
            //拆分语句
            MatchCollection MatchResults = SpokeParagraphSplit.Matches(originalText);

            foreach (Match m in MatchResults)
            {
                //获取代称
                List<string> AllSpokeMan = GetAllSpokeShortName(m.Value.Trim()).ToList();
                //对话排序
                List<SentenseInfo> SpokeSentenses = GetOrderBySentenses(m.Value.Trim(), JudgerCount, AllSpokeMan, paragraphAnalysisFactListItem.RegularCode);
                foreach (SentenseInfo info in SpokeSentenses)
                {
                    if (!string.IsNullOrEmpty(info.Name))
                    {
                        //审判人员判定
                        if (IsSporkerEqualsJudge(paragraphAnalysisFactListItem.RegularCode, info.Name))
                        {
                            #region 审判信息加载
                            //审判长-审判员信息
                            ElementExtractText model = new ElementExtractText();
                            model.E_ID = Snowflake.Instance().GetId().ToString();
                            var inquirer = paragraphAnalysisFactListItem.Inquirer;
                            var inquirerList = inquirer.Split(",").ToList();
                            List<ElementSpokeName> judger = spokenamelist.Where(a => inquirerList.Contains(a.ES_SuitDrgreeID)).ToList();
                            model.OriginalText = info.Text;
                            model.ParagraphName = paragraphAnalysisFactListItem.Code_Ch_Name;
                            model.ParagraphCode = paragraphAnalysisFactListItem.Code_Name;
                            if (judger.Count > 0)
                            {
                                model.SpokesmanID = judger[0].ES_ID;
                                model.AssertorID = judger[0].ES_ID;
                                model.AssertorSuitdegreeID = judger[0].ES_SuitDrgreeID;
                                model.SpokesmanName = "审";
                                model.AssertorName = judger[0].ES_FullName;
                            }
                            else
                            {
                                model.SpokesmanName = "审";
                                model.AssertorName = "审";
                            }
                            model.Structurenumber = info.sIndex;
                            spokeText.Add(model);
                            #endregion
                        }
                        else
                        {
                            #region 当事人信息
                            string name = info.Name;
                            if (dataContext.DataLayerAns.CaseType == "ldzc" && name == "被")
                            {
                                name = "被申请人";
                            }
                            if (name == "原")
                            {
                                name = "原告";
                            }
                            else if (name == "被")
                            {
                                name = "被告";
                            }
                            else if (name == "?")
                            {
                                name = "审判";
                            }

                            IList<ElementSpokeName> listname = GetRelatPerson(name);
                            IList<ElementSpokeName> listfyr = spokenamelist.Where(a => a.ES_SuitDegreeName == name).ToList();
                            foreach (ElementSpokeName ename in listname)
                            {
                                ElementExtractText model = new ElementExtractText();
                                model.ParagraphCode = paragraphAnalysisFactListItem.Code_Name;
                                model.ParagraphName = paragraphAnalysisFactListItem.Code_Ch_Name;
                                model.SpokesmanName = ename.ES_ShortName;
                                model.E_ID = Snowflake.Instance().GetId().ToString();
                                model.FL_ID = "";
                                model.OriginalText = info.Text;
                                model.SpokesmanID = ename.ES_ID;
                                string AssertorID = ename.ES_SuitDrgreeID;
                                string AssertorIDs = ename.ES_ID;
                                string AssertorName = ename.ES_FullName;
                                PersonnelAnalysisBase baseAnalysis = new PersonnelAnalysisBase();
                                baseAnalysis.spokenamelist = spokenamelist;
                                List<ElementSpokeName> spokeNamesList = baseAnalysis.GetMatchSpokeManByRoleName(listname, name).ToList();
                                if (spokeNamesList.Count > 0)
                                {
                                    var agent = paragraphAnalysisFactListItem.Agent;
                                    var agentList = agent.Split(",").ToList();
                                    ElementSpokeName elementSpoke = spokeNamesList[0];
                                    if (agentList.Contains(elementSpoke.ES_SuitDrgreeID))
                                    {

                                        var shiti = dataContext.DataLayerAns.Anjianshitis.FirstOrDefault(a => a.Anjianshitiid == elementSpoke.ES_ID);
                                        string spid = dataContext.DataLayerAns.Anjianshitijueses.FirstOrDefault(a => a.Anjianshitiid == shiti.Anjianshitiid).Zhuzhangfangjihe;
                                        //string spid = dataContext.DataLayerAns.FengXiCanShu.sourceDossierInfo.CaseEntityInfoList.FirstOrDefault(a => a.CE_ID == elementSpoke.ES_ID).EntityRoleList[0].ETR_AssertorIDList;
                                        ElementSpokeName elementname = spokenamelist.FirstOrDefault(a => a.ES_ID == spid);
                                        if (elementname != null)
                                        {
                                            AssertorID = elementname.ES_SuitDrgreeID;
                                            AssertorName = elementname.ES_FullName;
                                            AssertorIDs = elementname.ES_ID;
                                        }
                                        listname.Where(a => a.ES_ID == elementSpoke.ES_opid);
                                    }
                                }
                                model.AssertorSuitdegreeID = AssertorID;
                                model.AssertorID = AssertorIDs;
                                model.SpokesmanName = ename.ES_ShortName;
                                model.AssertorName = AssertorName;
                                model.Structurenumber = info.sIndex;
                                spokeText.Add(model);
                            }
                            #endregion

                        }
                    }
                    
                }
            }
        }

        /// <summary>
        /// 获取所有发言人代称
        /// </summary>
        /// <param name="courtText">庭审笔录正文</param>
        /// <returns>发言人代称列表</returns>
        /// [JudgeDocException]
        public IList<string> GetAllSpokeShortName(string courtText)
        {
            IList<string> allSpokeShortName = new List<string>();

            string regSpokeMenShortName = @"(?<=\r\s*|^)\S{1,10}(?=(?<!证据[\d一二三四五六七八九十]*)[：:])";
            MatchCollection matchArr = Regex.Matches(courtText, regSpokeMenShortName);
            foreach (Match omatch in matchArr)
            {

                if (Regex.IsMatch(omatch.Value, "[?^$\\*+.]") || !Regex.IsMatch("证实", omatch.Value))
                {
                    char[] chars = new char[] { ':', '：' };
                    string oValue = omatch.Value.Split(chars, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
                    if (!string.IsNullOrEmpty(oValue) && !allSpokeShortName.Contains(oValue))
                        allSpokeShortName.Add(oValue == "?" || oValue == "？" ? "\\" + oValue : oValue);
                }
            }

            return allSpokeShortName;
        }

        /// <summary>
        /// 获得段落中的发言人内容排序结果
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        //[JudgeDocException]
        public List<SentenseInfo> GetOrderBySentenses(string p, int judgecounter, List<string> allspokeman, string regCode)
        {
            try
            {
                List<SentenseInfo> SpokeSentenses = new List<SentenseInfo>();
                MatchCollection result = new Regex(string.Format(SentenseFormat, string.Join("|", allspokeman.ToArray())), RegexOptions.Singleline).Matches(p);

                if (allspokeman.Count > 0)
                {
                    foreach (Match m in result)
                    {
                        Match SpokeName = SpokeNameParse.Match(m.Value);

                        string oValue = "";
                        char[] chars = new char[] { ':', '：' };
                        oValue = SpokeName.Value.Split(chars, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();

                        if (string.IsNullOrEmpty(oValue) || IsSporkerEqualsJudge(regCode,oValue))//是审说的话或者无法识别认为是审
                        {
                            Tuple<string, string> tp = new Tuple<string, string>(SpokeName.Value == "" ? "审" : SpokeName.Value, p);
                            SpokeSentenses.Add(new SentenseInfo { sIndex = JudgerCount, Name = oValue == "" ? "审" : oValue, Text = m.Value });
                        }
                        else
                        {
                            Tuple<string, string> tp = new Tuple<string, string>(SpokeName.Value, p);
                            var lastspoke = SpokeSentenses.LastOrDefault(a => a.Name == oValue);//上一个说话的
                            if (lastspoke != null)
                            {
                                SpokeSentenses.Add(new SentenseInfo { sIndex = lastspoke.sIndex + 0.1m, Name = oValue, Text = m.Value });
                            }
                            else
                            {
                                SpokeSentenses.Add(new SentenseInfo { sIndex = JudgerCount + 0.1m, Name = oValue, Text = m.Value });
                            }
                        }

                    }

                    JudgerCount++;
                }
                return SpokeSentenses;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 判断人员名称是否是审
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        //[JudgeDocException]
        public virtual bool IsSporkerEqualsJudge(string name)
        {
            if (name == "审" || name == "?" || name == "？" || name == "问" || name == "审判长" || name == "审判员" || name == "长")
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 判断人员名称是否是审
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        //[JudgeDocException]
        public virtual bool IsSporkerEqualsJudge(string regCode, string name)
        {
            List<string> listParse = RuleParseClass.GetParseRegCodeList(regCode, name);
            if (listParse?.Count>0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 人员信息加载
        /// </summary>
        public void LoadPersonnelInformation()
        {
            if (dataContext.DataLayerAns.Anjianshitis != null)
            {
                //dataContext.DataLayerAns.Anjianshitis.Where(x=>x.Chutingqk!="0")
                foreach (An_anjianshiti infoItem in dataContext.DataLayerAns.Anjianshitis)
                {
                    // 获取角色信息
                    An_anjianshitijuese anjianshitijuese = new An_anjianshitijuese();
                    anjianshitijuese = dataContext.DataLayerAns.Anjianshitijueses.Where(a => a.Anjianshitiid == infoItem.Anjianshitiid).FirstOrDefault();

                    // 实体赋值
                    ElementSpokeName elementSpokeName = new ElementSpokeName();
                    elementSpokeName.ES_ID = infoItem.Anjianshitiid;
                    elementSpokeName.ES_FullName = infoItem.Mingcheng;
                    elementSpokeName.ES_SuitDrgreeID = anjianshitijuese.Juesesusongdiwei;
                    elementSpokeName.ES_SuitDegreeName = anjianshitijuese.SusongDiwei;
                    if (!string.IsNullOrEmpty(anjianshitijuese.Fayanrenmingcheng))
                    {
                        elementSpokeName.ES_ShortName = anjianshitijuese.Fayanrenmingcheng;
                    }
                   // elementSpokeName.ES_ShortName = infoItem.Jiancheng;
                    elementSpokeName.ES_Role = anjianshitijuese.Juesemingcheng;
                    elementSpokeName.Sp_id = anjianshitijuese.Zhuzhangfangjihe;
                    elementSpokeName.ES_Sex = infoItem.Xingbie;
                    elementSpokeName.ES_AssertorID = anjianshitijuese.Zhuzhangfangjihe;
                    elementSpokeName.ES_RoleIndex = anjianshitijuese.Juesexuhao.ToString();
                    elementSpokeName.Sp_participanttypeid = anjianshitijuese.Dangshirenleixing;
                    spokenamelist.Add(elementSpokeName);
                }
                 dataContext.DataLayerAns.ElementSpokeList = spokenamelist;
            }
        }

        /// <summary>
        /// 获取名称集合
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<ElementSpokeName> GetRelatPerson(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                return new List<ElementSpokeName>();
            }
            List<ElementSpokeName> listname = spokenamelist.Where(a => a.ES_ShortName!=null && a.ES_ShortName.Contains(name)).ToList();
            if (listname.Count == 0)
            {
                name = personnelAnalysis.ReplaceShortNameToFullName(spokenamelist, name, "1");
                if (name.IndexOf("、") > 0)
                {
                    string[] names = name.Split('、').ToArray();
                    if (names.Length > 0)
                    {
                        foreach (string str in names)
                        {
                            if (spokenamelist.Any(a => a.ES_FullName == str))
                                listname.Add(spokenamelist.First(a => a.ES_FullName == str));
                        }
                    }
                }
                else
                {
                    listname = spokenamelist.Where(a => a.ES_FullName.Contains(name)).ToList();
                }
            }
            else
            {
                listname = spokenamelist.Where(a => a.ES_ShortName != null && a.ES_ShortName.IndexOf(name)>-1).ToList();
            }
            return listname;
        }
        #endregion

        #region 对象保存

        /// <summary>
        /// 保存人员段落对话数据
        /// </summary>
        public void PersonSave()
        {
            foreach (ElementExtractText elementItem in spokeText)
            {
                if (!string.IsNullOrEmpty(elementItem.AssertorName))
                {
                    An_anjianshiti shiti = dataContext.DataLayerAns.Anjianshitis.FirstOrDefault(a=>a.Mingcheng == elementItem.AssertorName);
                    //if (shiti != null)
                    //{
                        An_fayanrenduanluoxinxi fayanrenduanluoxinxi = new An_fayanrenduanluoxinxi();
                        fayanrenduanluoxinxi.Fayanrenduoluoid = Snowflake.Instance().GetId().ToString();
                        fayanrenduanluoxinxi.Duanluobianhao = elementItem.ParagraphCode;
                        fayanrenduanluoxinxi.Duanluoneirong = elementItem.OriginalText;
                        fayanrenduanluoxinxi.Duanluoxuhao = elementItem.Structurenumber;
                        fayanrenduanluoxinxi.Fayanrenmingcheng = elementItem.SpokesmanName;
                        fayanrenduanluoxinxi.Shujuid = shiti?.Shujuid;
                        fayanrenduanluoxinxi.Jueseid = shiti?.Anjianshitijueses.FirstOrDefault().Jueseid;
                        if (dataContext.DataLayerAns.Fayanrenduanluoxinxis==null)
                        {
                            dataContext.DataLayerAns.Fayanrenduanluoxinxis = new List<An_fayanrenduanluoxinxi>();
                        }
                        dataContext.DataLayerAns.Fayanrenduanluoxinxis.Add(fayanrenduanluoxinxi);

                    //}
                }
            }
        }
        #endregion
    }
}
